﻿using Bricks.Business.Models.Account;
using Bricks.Business.Data.Repositories.Account;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using Bricks.Component.Utils;
using Bricks.Site.Models.Purview;

namespace Bricks.Business.Service.Impl
{
    [Export(typeof(IMenuInfoService))]
    public class MenuInfoService : IMenuInfoService
    {
        #region 保护属性
        [Import]
        protected IMenuInfoRepository MenuInfoRepository { get; set; }

        [Import]
        protected IMenuActionRepository MenuActionRepository { get; set; }

        [Import]
        protected IUserMenuActionRepository UserMenuActionRepository { get; set; }
        #endregion

        #region 公共属性
        public IQueryable<MenuInfo> Menues
        {
            get
            {
                return MenuInfoRepository.Entities;
            }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public OperationResult Add(MenuInfo model)
        {
            PublicHelper.CheckArgument(model, "model");
            MenuInfo record = model.CopyTo<MenuInfo>();
            record.ID = GuidHelper.NewGuid();
            record.OrderNo = MenuInfoRepository.GetNextOrderNo(m => m.OrderNo);  //获取下一个排序号
            MenuInfoRepository.Insert(record);
            return new OperationResult(OperationResultType.Success, "新增成功", record);
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public OperationResult Modify(MenuInfo model)
        {
            PublicHelper.CheckArgument(model, "model");
            MenuInfo record = Menues.FirstOrDefault(m => m.ID == model.ID);
            if (record == null)
                return new OperationResult(OperationResultType.QueryNull, "未找到指定的记录");

            record = model.CopyTo<MenuInfo>();
            if (MenuInfoRepository.Update(record) >= 0)
                return new OperationResult(OperationResultType.Success, "修改成功", record);
            return new OperationResult(OperationResultType.Error, "保存失败");
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public OperationResult Delete(Guid id)
        {
            MenuInfo record = Menues.FirstOrDefault(m => m.ID == id);
            if (record == null)
                return new OperationResult(OperationResultType.QueryNull, "未找到指定的记录");

            //删除菜单对应的菜单功能
            var menuActions = MenuActionRepository.Entities.Where(m => m.MenuID == id);
            if (menuActions != null && menuActions.Count() > 0)
            {
                MenuActionRepository.Delete(menuActions);
            }

            if (MenuInfoRepository.Delete(record) >= 0)
                return new OperationResult(OperationResultType.Success, "删除成功", record);
            return new OperationResult(OperationResultType.Error, "删除失败");
        }

        /// <summary>
        /// 排序设置(向上向下)
        /// </summary>
        /// <param name="id"></param>
        /// <param name="pid"></param>
        /// <param name="upOrDown"></param>
        /// <returns></returns>
        public OperationResult SetOrder(Guid id, Guid? pid, string upOrDown)
        {
            IQueryable<MenuInfo> entities = null;
            if (pid.HasValue)
            {
                entities = MenuInfoRepository.Entities.Where(m => m.PID == pid.Value);  //找出可能涉及排序的实体集合（同一PID下）
            }
            else
            {
                entities = MenuInfoRepository.Entities.Where(m => m.PID == null);  //找出可能涉及排序的实体集合（同一PID下）
            }
            var exeResult = MenuInfoRepository.SetOrder(entities, id, "OrderNo", upOrDown);  //执行向上向下操作
            return exeResult;
        }

        /// <summary>
        /// 获取菜单功能列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IQueryable<MenuAction> GetMenuActionList(Guid id)
        {
            //List<MenuAction> result = new List<MenuAction>();
            var query = from m in MenuActionRepository.Entities
                        where m.MenuID == id
                        orderby m.OrderNo
                        select m;
            //result = query.ToList();
            return query;
        }

        /// <summary>
        /// 保存功能分配
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public OperationResult SaveAssign(Guid menuID, List<MenuActionAssignView> list)
        {
            OperationResult result = new OperationResult(OperationResultType.NoChanged);
            try
            {
                #region 旧设计（此处的思路是直接清空数据库原有的记录，然后重新加上已配置的记录）
                ////找出原有的记录
                //var existMenuActions = MenuActionRepository.Entities.Where(m => m.MenuID == menuID).ToList();  //此处必须ToList，否则以下foreach将报错
                //if (existMenuActions != null && existMenuActions.Count() > 0)
                //{
                //    //清空处理
                //    foreach (var ma in existMenuActions)
                //    {
                //        MenuActionRepository.Delete(ma);
                //    }
                //}
                //int orderNo = 1;
                ////加上已配置的记录，同时重新排列OrderNo
                //foreach (var item in list)
                //{
                //    MenuAction newMA = item.CopyTo<MenuAction>();
                //    newMA.ID = GuidHelper.NewGuid();
                //    newMA.MenuID = menuID;
                //    newMA.OrderNo = orderNo;
                //    MenuActionRepository.Insert(newMA);
                //    orderNo++;
                //}
                //result = new OperationResult(OperationResultType.Success, "保存成功");
                #endregion

                #region 新设计
                //处理删除的情况，如果list中已删除，则删除数据库对应记录，并删除用户授权
                var existMenuActions = MenuActionRepository.Entities.Where(m => m.MenuID == menuID).ToList();  //此处必须ToList，否则以下foreach将报错
                if (existMenuActions != null && existMenuActions.Count() > 0)
                {
                    foreach (var ma in existMenuActions)
                    {
                        var isExistList = list.Any(m => m.ID == ma.ID);
                        //如果不存在了，则删除
                        if (!isExistList)
                        {
                            //还要关联删除UserMenuAction
                            var userMenuActions = UserMenuActionRepository.Entities.Where(m => m.MenuActionID == ma.ID).ToList();
                            if (userMenuActions != null)
                            {
                                UserMenuActionRepository.Delete(userMenuActions);
                            }
                            //删除菜单功能
                            MenuActionRepository.Delete(ma);
                        }
                    }
                }
                //处理修改和新增的情况
                int orderNo = 1;
                foreach (var item in list)
                {
                    //修改（原来存在则以这种方式）
                    var ma = MenuActionRepository.Entities.FirstOrDefault(m => m.ID == item.ID);
                    if (ma != null)
                    {
                        ma = item.CopyTo<MenuAction>();
                        ma.MenuID = menuID;
                        ma.OrderNo = orderNo;
                        MenuActionRepository.Update(ma);
                    }
                    //新增
                    else
                    {
                        MenuAction newMA = item.CopyTo<MenuAction>();
                        newMA.ID = GuidHelper.NewGuid();
                        newMA.MenuID = menuID;
                        newMA.OrderNo = orderNo;
                        MenuActionRepository.Insert(newMA);
                    }
                    orderNo++;
                }
                result = new OperationResult(OperationResultType.Success, "保存成功");
                #endregion
            }
            catch (Exception ex)
            {
                result = new OperationResult(OperationResultType.Error, ex.Message);
            }
            return result;
        }
        #endregion

        /// <summary>
        /// 根据ID获取菜单的信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public MenuInfo GetMenuInfo(Guid id)
        {
            MenuInfo result = null;
            if (id != null && id != Guid.Empty)
            {
                result = Menues.FirstOrDefault(m => m.ID == id);
            }
            return result;
        }

        /// <summary>
        /// 获取模块和菜单名称
        /// Tuple1：模块名称
        /// Tuple2：菜单名称
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public string GetModelAndMenuName(string tag)
        {
            //string modelName = string.Empty;
            //string menuName = string.Empty;

            string result = string.Empty;

            if (!String.IsNullOrEmpty(tag))
            {
                string[] tagSplit = tag.Split('/');
                if (tagSplit != null && tagSplit.Length > 2)
                {
                    string modelCode = tagSplit[0];  //模块（一级菜单）Code
                    string menuCode = tagSplit[1];  //菜单（二级菜单）Code

                    var model = MenuInfoRepository.Entities.FirstOrDefault(m => m.MenuCode == modelCode && (m.PID == null || m.PID == Guid.Empty));
                    if (model != null)
                    {
                        result = model.MenuName;

                        var menu = MenuInfoRepository.Entities.FirstOrDefault(m => m.MenuCode == menuCode && m.PID == model.ID);
                        if (menu != null)
                        {
                            result += "-" + menu.MenuName;
                        }
                    }
                }
            }
            //return new Tuple<string, string>(modelName, menuName);
            return result;
        }
    }
}
